/*
 *--------------------------------------------------------------------------
 *   Battlefield - A Realtime Network Multiplayer Game
 *   =======================================================
 *   Developed by Group D02 - 2009/2010 Semester 4 - CS2103
 *     Harry Nguyen Duy Hoang <nnduyhoang@yahoo.co.uk>
 *     Kent Chng Siang Rong <fivefootway@gmail.com>
 *     Lim Yong Peng <limpeng1986@gmail.com>
 *     Loh Xiankun <u0807185@nus.edu.sg>
 *   Instructed by
 *     Dr. Damith C.Rajapakse <damith@gmail.com>
 *   =======================================================
 *   $Id: TacticalPhaseScreen.java 607 2010-07-27 07:16:34Z Harry $
 *   $LastChangedDate: 2010-07-27 07:16:34 +0000 (Tue, 27 Jul 2010) $
 *   $LastChangedBy: Harry $
 *--------------------------------------------------------------------------
 */
package battlefield.ui.screen;

import battlefield.resource.Graphics;
import battlefield.resource.Sounds;
import battlefield.entity.Unit;
import battlefield.entity.UnitModel;
import battlefield.resource.Music;
import battlefield.state.UnitType;
import battlefield.ui.component.InventoryButton;
import battlefield.ui.component.InventoryPanel;
import battlefield.ui.component.MapButton;
import battlefield.ui.component.MapPanel;
import battlefield.ui.component.MessagePanel;
import battlefield.ui.component.ReadyButton;
import battlefield.ui.component.StatusPanel;
import battlefield.ui.component.GameTabPane;
import battlefield.util.ExceptionUtils;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.ArrayList;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;

/**
 *
 * @author Harry Nguyen
 */
public class TacticalPhaseScreen extends Screen implements ActionListener {

    private StatusPanel statusPanel;
    private MessagePanel messagePanel;
    private MapPanel mapPanel;
    private InventoryPanel inventoryPanel;
    private GameTabPane tabbedPane;
    private Timer t;
    private ReadyButton end;

    public TacticalPhaseScreen() {
        initComponents();
    }

    private void initComponents() {
        statusPanel = new StatusPanel(getPlayer(true), getOpponent(true));
        messagePanel = new MessagePanel();

        try {
            mapPanel = new MapPanel(getPlayer().getMap(), true);
            ArrayList<UnitModel> models = new ArrayList<UnitModel>();
            for (UnitModel model : getLogic().getUnitModels()) {
                if (model.getType() == UnitType.TOOL || model.getType() == UnitType.EQUIPMENT) {
                    models.add(model);
                }
            }
            inventoryPanel = new InventoryPanel(models);
        } catch (RemoteException ex) {
        }

        end = new ReadyButton();

        mapPanel.addActionListener(this, "PLACE_EQUIPMENT");
        inventoryPanel.addActionListener(this, "SELECT_UNIT");
        end.addActionListener(this);
        statusPanel.setPreferredSize(new Dimension(450, 41));
        messagePanel.setPreferredSize(new Dimension(450, 41));
        mapPanel.setPreferredSize(new Dimension(448, 448));
        inventoryPanel.setPreferredSize(new Dimension(800, 180));
        end.setPreferredSize(new Dimension(128, 128));
        tabbedPane = new GameTabPane(JTabbedPane.LEFT, JTabbedPane.WRAP_TAB_LAYOUT);
        tabbedPane.addTab("", inventoryPanel);
        tabbedPane.setTabComponentAt(0, new JLabel(new ImageIcon(Graphics.TAB_TITLE_INVENTORY.getImage())));
        tabbedPane.setPreferredSize(new Dimension(880, 200));

        this.setBackgroundImage(Graphics.BACKGROUND_MAIN.getImage());
        GroupLayout layout = new GroupLayout(this);
        this.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        layout.setHorizontalGroup(
                layout.createSequentialGroup().addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addComponent(statusPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(messagePanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addGroup(layout.createSequentialGroup().addGap(261, 261, 261).addComponent(mapPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(end, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)));
        layout.setVerticalGroup(
                layout.createSequentialGroup().addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(statusPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(messagePanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(mapPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addComponent(end, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addComponent(tabbedPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE));

        statusPanel.update(getPlayer(true), getOpponent(true));

        if (Music.LOADING.isRunning()) {
            Music.LOADING.stop();
        }
        if (!Music.TACTICAL_PHASE.isRunning()) {
            Music.TACTICAL_PHASE.start();
        }
    }

    /* Begin Region: State Pattern */
    @Override
    public Screen startWar() {
        return new WarPhaseScreen();
    }
    /* End Region: State Pattern */

    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(t)) {
            if (getGame(true).isPhaseCompleted()) {
                t.stop();
                getGUI().startWar();
            }
        } else if (e.getActionCommand().equals("SELECT_UNIT") && e.getSource() instanceof InventoryButton) {
            InventoryButton button = (InventoryButton) e.getSource();
            UnitModel model = button.getUnitModel();
            mapPanel.setPreviewUnit(new Unit(0, model));
        } else if (e.getActionCommand().equals("SELL_EQUIPMENT") && e.getSource() instanceof MapButton) {
            Unit previewUnit = mapPanel.getPreviewUnit();

            if (previewUnit == null) {
                return;
            }

            UnitModel model = previewUnit.getModel();

            if (model.getType() != UnitType.TOOL) {
                // TODO: Play sound ... display message
                messagePanel.updateMessage("Must be a tool.");
                Sounds.ERROR.play();
                //JOptionPane.showMessageDialog(this, "Must be an equipment.");
                return;
            }

            try {
                MapButton button = (MapButton) e.getSource();
                getLogic().sellUnitOnMap(getPlayer().getId(), button.getRow(), button.getColumn());
                Sounds.UNIT_SOLD.play();
                getLogic().updateUnitCounts(getPlayer().getId());
                getLogic().updateUnitCounts(getOpponent().getId());
                mapPanel.update(getPlayer(true).getMap());
                inventoryPanel.update();
                statusPanel.update(getPlayer(true), getOpponent(true));
            } catch (RemoteException ex) {
                messagePanel.updateMessage(ExceptionUtils.getMessage(ex));
                Sounds.ERROR.play();
                //JOptionPane.showMessageDialog(this, ExceptionUtils.getMessage(ex));
            }
        } else if (e.getActionCommand().equals("PLACE_EQUIPMENT") && e.getSource() instanceof MapButton) {
            Unit previewUnit = mapPanel.getPreviewUnit();

            if (previewUnit == null) {
                return;
            }

            UnitModel model = previewUnit.getModel();

            if (model.getType() == UnitType.TOOL) {
                actionPerformed(new ActionEvent(e.getSource(), e.getID(), "SELL_EQUIPMENT"));
                return;
            }


            if (model.getType() != UnitType.EQUIPMENT) {
                // TODO: Play sound ... display message
                messagePanel.updateMessage("Must be an equipment.");
                Sounds.ERROR.play();
                //JOptionPane.showMessageDialog(this, "Must be an equipment.");
                return;
            }

            try {
                MapButton button = (MapButton) e.getSource();
                getLogic().buyAndPlaceUnitOnMap(getPlayer().getId(), mapPanel.getPreviewUnit().getModel().getId(), button.getRow(), button.getColumn());
                Sounds.MOUSE_CLICK.play();
                getLogic().updateUnitCounts(getPlayer().getId());
                getLogic().updateUnitCounts(getOpponent().getId());
                mapPanel.update(getPlayer(true).getMap());
                inventoryPanel.update();
                statusPanel.update(getPlayer(true), getOpponent(true));
            } catch (RemoteException ex) {
                messagePanel.updateMessage(ExceptionUtils.getMessage(ex));
                Sounds.ERROR.play();
                //JOptionPane.showMessageDialog(this, ExceptionUtils.getMessage(ex));
            }
        } else if (e.getSource().equals(end)) {
            try {
                getLogic().endTacticalPhase(getPlayer().getId());
                this.removeAll();
                ImageIcon newBackImage;
                Image newImage;
                newBackImage = new ImageIcon(Graphics.SCREEN_LOADING.getImage());
                newImage = newBackImage.getImage();
                this.getGraphics().drawImage(newImage, 0, 0, this);
                //Music.LOADING.start();
                if (Music.TACTICAL_PHASE.isRunning()) {
                    Music.TACTICAL_PHASE.stop();
                }
                if (!Music.LOADING.isRunning()) {
                    Music.LOADING.start();
                }
                t = new Timer(2000, this);
                t.start();
            } catch (RemoteException ex) {
                messagePanel.updateMessage(ExceptionUtils.getMessage(ex));
                Sounds.ERROR.play();
                //JOptionPane.showMessageDialog(this, ExceptionUtils.getMessage(ex));
            }
        }
    }

    @Override
    protected void finalize() throws Throwable {
        if (t != null && t.isRunning()) {
            t.stop();
        }
        t = null;
        super.finalize();
    }
}
